package cn.jolyoulu.adminweb.aspects;

import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import cn.jolyoulu.adminweb.entity.bo.LoginBO;
import cn.jolyoulu.common.core.utils.net.IPUtils;
import cn.jolyoulu.common.web.entity.ResultInfo;
import cn.jolyoulu.common.web.excption.GlobalException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import cn.jolyoulu.cmnservice.entity.po.SysLoginLog;
import cn.jolyoulu.cmnservice.serivce.SysIpRangeService;
import cn.jolyoulu.cmnservice.serivce.SysLoginLogService;

import java.time.LocalDateTime;

/**
 * @Author LuZhouJin
 * @Date 2023/3/21
 * 登录日志
 */
@Slf4j
@Aspect
@Component
public class LoginLogAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private SysLoginLogService sysLoginLogService;

    @Autowired
    private SysIpRangeService sysIpRangeService;

    @Pointcut(value = "execution(* cn.jolyoulu.adminweb.controller.auth.ApiSysUserAuthController.login(..))")
    private void loginPointcut(){}

    @Around("loginPointcut()")
    public Object loginPointcutAround(ProceedingJoinPoint pjp) throws Throwable {
        SysLoginLog loginLog = new SysLoginLog();
        try {
            Object res = pjp.proceed();
            succeed(loginLog,res);
            return res;
        }catch (GlobalException e){
            error(loginLog,e);
            throw e;
        }finally {
            addLog(loginLog,pjp.getArgs()[0]);
        }
    }

    /**
     * 记录正常返回结果
     */
    private void succeed(SysLoginLog loginLog,Object res) {
        loginLog.setStatus(0);
        if (res instanceof ResultInfo){
            loginLog.setMsg(((ResultInfo<?>) res).getMsg());
        }
    }

    /**
     * 记录异常结果
     */
    private void error(SysLoginLog loginLog,GlobalException e) {
        loginLog.setStatus(1);
        loginLog.setMsg(e.getMessage());
    }

    /**
     * 保存记录
     */
    private void addLog(SysLoginLog loginLog,Object arg) {
        if (!(arg instanceof LoginBO)){
            return; //不处理
        }
        try {
            LoginBO bo = (LoginBO) arg;
            loginLog.setLoginTime(LocalDateTime.now());
            loginLog.setAccount(bo.getAccount());
            UserAgent userAgent = UserAgentUtil.parse(request.getHeader("user-agent"));
            String clientIP = "127.0.0.1";
            loginLog.setIpaddr(clientIP);
            loginLog.setBrowser(userAgent.getBrowser().toString());
            loginLog.setOs(userAgent.getOs().toString());
            loginLog.setLoginTime(LocalDateTime.now());
            loginLog.setLoginLocation(sysIpRangeService.getLocationByIPNum(IPUtils.ipToNumber(clientIP)));
            sysLoginLogService.save(loginLog);
        }catch (Exception e){
            log.error("登录日志记录失败",e);
        }
    }

}
